import React, { useRef, useEffect, useState } from "react";
import { Canvas, useFrame } from "@react-three/fiber";
import { OrbitControls, ContactShadows } from "@react-three/drei";
import * as THREE from "three";
// @ts-expect-error: FBXLoader is not typed in three/examples/jsm/loaders
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader";
import { useThemeContext } from "../../app/ThemeContext";

const MODEL_LIST = [
    { label: "跳操活动", value: "/modules/Hip Hop Dancing.fbx" },
    { label: "高边腿", value: "/modules/Martelo 2.fbx" },
    { label: "街舞", value: "/modules/Breakdance 1990.fbx" },
    { label: "跳舞", value: "/modules/Rumba Dancing.fbx" },
];

// 敏感词列表
const SENSITIVE_WORDS = ["傻逼", "操你妈", "sb", "cnm"];

// 敏感词过滤函数
const filterSensitiveWords = (text: string): string => {
    let filteredText = text;
    SENSITIVE_WORDS.forEach((word) => {
        const regex = new RegExp(word, "gi");
        filteredText = filteredText.replace(regex, "*".repeat(word.length));
    });
    return filteredText;
};

function FbxModel({ url }: { url: string }) {
    const group = useRef<THREE.Group>(null);
    const mixer = useRef<THREE.AnimationMixer>();

    useEffect(() => {
        const loader = new FBXLoader();
        let model: THREE.Group | undefined;
        loader.load(
            url,
            (fbx: THREE.Group & { animations?: THREE.AnimationClip[] }) => {
                model = fbx;
                model.scale.set(0.01, 0.01, 0.01);
                model.position.set(0, 0, 0);
                if (group.current) {
                    group.current.add(model);
                }
                if (fbx.animations && fbx.animations.length > 0) {
                    mixer.current = new THREE.AnimationMixer(fbx);
                    mixer.current.clipAction(fbx.animations[0]).play();
                }
            }
        );
        return () => {
            if (group.current && model) {
                group.current.remove(model);
            }
        };
    }, [url]);

    useFrame((_, delta) => {
        if (mixer.current) {
            mixer.current.update(delta);
        }
    });

    return <group ref={group} />;
}

const DANMU_STORAGE_KEY = "user_video_danmu_list";

function Index() {
    const { theme } = useThemeContext();
    const [modelIndex, setModelIndex] = useState(0);
    // 弹幕输入
    const [danmuInput, setDanmuInput] = useState("");
    // 所有弹幕（持久化）
    const [danmuList, setDanmuList] = useState<
        {
            text: string;
            top: number;
            key: string;
            time: number;
        }[]
    >([]);
    // 当前正在显示的弹幕
    const [activeDanmus, setActiveDanmus] = useState<typeof danmuList>([]);
    // 弹幕显示/隐藏
    const [danmuVisible, setDanmuVisible] = useState(true);
    // 弹幕字体大小
    const [danmuFontSize, setDanmuFontSize] = useState(20);
    // 弹幕设置面板显示/隐藏
    const [showDanmuPanel, setShowDanmuPanel] = useState(false);
    const videoRef = useRef<HTMLVideoElement>(null);
    const danmuAreaRef = useRef<HTMLDivElement>(null);

    // 初始化弹幕列表（从localStorage）
    useEffect(() => {
        const saved = localStorage.getItem(DANMU_STORAGE_KEY);
        if (saved) {
            try {
                setDanmuList(JSON.parse(saved));
            } catch (error) {
                console.error("Failed to parse saved danmu list:", error);
            }
        }
    }, []);

    // 弹幕列表变化时存储到localStorage
    useEffect(() => {
        localStorage.setItem(DANMU_STORAGE_KEY, JSON.stringify(danmuList));
    }, [danmuList]);

    // 视频暂停/播放状态
    const [isVideoPaused, setIsVideoPaused] = useState(false);
    // 弹幕暂停时的位置记录
    const [pausedDanmuPositions, setPausedDanmuPositions] = useState<
        Record<string, number>
    >({});

    // 监听视频播放/暂停状态
    useEffect(() => {
        const video = videoRef.current;
        if (!video) return;

        const handlePlay = () => {
            setIsVideoPaused(false);
            // 清除暂停位置记录
            setPausedDanmuPositions({});
        };
        const handlePause = () => {
            setIsVideoPaused(true);
            // 记录当前弹幕位置
            const positions: Record<string, number> = {};
            activeDanmus.forEach((dm) => {
                const element = document.querySelector(
                    `[data-danmu-key="${dm.key}"]`
                ) as HTMLElement;
                if (element) {
                    const computedStyle = window.getComputedStyle(element);
                    const left = parseFloat(computedStyle.left) || 0;
                    positions[dm.key] = left;
                }
            });
            setPausedDanmuPositions(positions);
        };

        video.addEventListener("play", handlePlay);
        video.addEventListener("pause", handlePause);

        return () => {
            video.removeEventListener("play", handlePlay);
            video.removeEventListener("pause", handlePause);
        };
    }, [activeDanmus]);

    // 发送弹幕，记录当前视频时间
    const handleSendDanmu = () => {
        if (!danmuInput.trim() || !videoRef.current) return;
        const areaHeight = danmuAreaRef.current?.offsetHeight || 340;
        const top = Math.random() * (areaHeight - 32);
        const newDanmu = {
            text: filterSensitiveWords(danmuInput), // 过滤敏感词
            top,
            key: Date.now() + Math.random() + "",
            time: videoRef.current!.currentTime,
        };
        setDanmuList((prev) => [...prev, newDanmu]);
        setDanmuInput("");
    };

    // 监听视频播放进度，触发弹幕（每次到达时间点都可触发）
    useEffect(() => {
        const video = videoRef.current;
        if (!video) return;
        let triggered: Record<string, boolean> = {};

        const handleTimeUpdate = () => {
            const cur = video.currentTime;
            setDanmuList((list) => {
                const toShow: typeof danmuList = [];
                list.forEach((dm) => {
                    // 检查弹幕是否在时间范围内且未被触发过
                    if (!triggered[dm.key] && Math.abs(cur - dm.time) < 0.3) {
                        toShow.push(dm);
                        triggered[dm.key] = true;
                    }
                });
                if (toShow.length > 0) {
                    setActiveDanmus((ad) => [...ad, ...toShow]);
                }
                return list;
            });
        };

        video.addEventListener("timeupdate", handleTimeUpdate);

        // 拖动回退时，重置triggered，允许弹幕重新显示
        const handleSeeked = () => {
            triggered = {};
        };
        video.addEventListener("seeked", handleSeeked);

        return () => {
            video.removeEventListener("timeupdate", handleTimeUpdate);
            video.removeEventListener("seeked", handleSeeked);
        };
    }, []);

    // 弹幕动画结束后自动移除
    useEffect(() => {
        if (activeDanmus.length === 0) return;
        const timers: ReturnType<typeof setTimeout>[] = [];

        activeDanmus.forEach((dm) => {
            timers.push(
                setTimeout(() => {
                    // 从活跃弹幕中移除，但保留在弹幕列表中以便重新播放
                    setActiveDanmus((prev) =>
                        prev.filter((d) => d.key !== dm.key)
                    );
                }, 8000)
            );
        });

        return () => {
            timers.forEach((t) => clearTimeout(t));
        };
    }, [activeDanmus]);

    const handleInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
        if (e.key === "Enter") handleSendDanmu();
    };

    const handleSelectChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
        setModelIndex(Number(e.target.value));
    };

    // 主题自适应背景色
    const bg =
        theme === "dark"
            ? "linear-gradient(120deg, #181c27 0%, #232526 100%)"
            : "linear-gradient(120deg, #f5f6fa 0%, #e9ecef 100%)";

    return (
        <div
            style={{
                minHeight: "100vh",
                width: "100vw",
                background: bg,
                display: "flex",
                alignItems: "flex-start", // 顶部对齐
                justifyContent: "flex-start", // 左侧对齐
                padding: 0,
            }}
        >
            <div
                style={{
                    display: "flex",
                    gap: 32,
                    width: "100vw",
                    maxWidth: "100vw",
                    justifyContent: "flex-start", // 左侧对齐
                    margin: 0,
                }}
            >
                {/* 左侧卡片 */}
                <div
                    style={{
                        width: "50vw",
                        maxWidth: 900,
                        minHeight: 800,
                        background: "rgba(255,255,255,0.95)",
                        borderRadius: 24,
                        boxShadow: "0 8px 32px rgba(0,0,0,0.18)",
                        padding: 48,
                        display: "flex",
                        flexDirection: "column",
                        alignItems: "center",
                        justifyContent: "center",
                        margin: 0,
                    }}
                >
                    {/* 原左侧内容 */}
                    <div style={{ textAlign: "center", padding: "16px 0" }}>
                        <select
                            value={modelIndex}
                            onChange={handleSelectChange}
                            style={{
                                fontSize: 18,
                                padding: "6px 16px",
                                borderRadius: 8,
                                border: "1px solid #ccc",
                            }}
                        >
                            {MODEL_LIST.map((item, idx) => (
                                <option
                                    value={idx}
                                    key={item.value}
                                    style={{ color: "#000" }}
                                >
                                    {item.label}
                                </option>
                            ))}
                        </select>
                    </div>
                    <div
                        style={{
                            width: "100%",
                            height: 600,
                            borderRadius: 16,
                            overflow: "hidden",
                            background: "#eceff1",
                            boxShadow: "0 2px 8px #0001",
                        }}
                    >
                        <Canvas
                            camera={{ position: [0, 1.2, 3.5], fov: 45 }}
                            shadows
                        >
                            {/* 柔和环境光和主光源 */}
                            <ambientLight intensity={0.5} />
                            <directionalLight
                                position={[2, 6, 3]}
                                intensity={1.2}
                                castShadow
                                shadow-mapSize-width={1024}
                                shadow-mapSize-height={1024}
                            />
                            {/* 地面 */}
                            <mesh
                                receiveShadow
                                rotation={[-Math.PI / 2, 0, 0]}
                                position={[0, -0.02, 0]}
                            >
                                <planeGeometry args={[10, 10]} />
                                <meshStandardMaterial color="#e0e0e0" />
                            </mesh>
                            {/* 模型 */}
                            <FbxModel url={MODEL_LIST[modelIndex].value} />
                            {/* 柔和接触阴影 */}
                            <ContactShadows
                                position={[0, -0.01, 0]}
                                opacity={0.4}
                                scale={5}
                                blur={1.5}
                                far={1.5}
                            />
                            <OrbitControls
                                enablePan={false}
                                minDistance={2}
                                maxDistance={8}
                            />
                        </Canvas>
                    </div>
                </div>
                {/* 右侧卡片 */}
                <div
                    style={{
                        width: "50vw",
                        maxWidth: 900,
                        minHeight: 800,
                        background: "rgba(255,255,255,0.95)",
                        borderRadius: 24,
                        boxShadow: "0 8px 32px rgba(0,0,0,0.18)",
                        padding: 48,
                        display: "flex",
                        flexDirection: "column",
                        alignItems: "center",
                        justifyContent: "center",
                        margin: 0,
                    }}
                >
                    {/* 右侧原内容（视频弹幕区） */}
                    <div style={{ textAlign: "center", marginBottom: 24 }}>
                        <h2
                            style={{
                                color: "#222",
                                marginBottom: 8,
                                fontSize: 28,
                                fontWeight: 600,
                                letterSpacing: 2,
                            }}
                        >
                            示例视频
                        </h2>
                        <p style={{ color: "#666", fontSize: 14 }}>
                            已保存弹幕：{danmuList.length} 条
                        </p>
                    </div>
                    <div style={{ display: "flex", gap: 12, marginBottom: 12 }}>
                        <button
                            onClick={() => setShowDanmuPanel((v) => !v)}
                            style={{
                                background: "#222",
                                color: "#fff",
                                border: "none",
                                borderRadius: 8,
                                padding: "8px 24px",
                                fontSize: 18,
                                fontWeight: 500,
                                cursor: "pointer",
                                boxShadow: "0 2px 8px #0002",
                                display: "flex",
                                alignItems: "center",
                                gap: 8,
                            }}
                        >
                            <span role="img" aria-label="设置">
                                ⚙️
                            </span>{" "}
                            弹幕设置
                        </button>
                        <button
                            onClick={() => {
                                if (window.confirm("确定要清除所有弹幕吗？")) {
                                    setDanmuList([]);
                                    setActiveDanmus([]);
                                    localStorage.removeItem(DANMU_STORAGE_KEY);
                                }
                            }}
                            style={{
                                background: "#dc3545",
                                color: "#fff",
                                border: "none",
                                borderRadius: 8,
                                padding: "8px 24px",
                                fontSize: 18,
                                fontWeight: 500,
                                cursor: "pointer",
                                boxShadow: "0 2px 8px #0002",
                                display: "flex",
                                alignItems: "center",
                                gap: 8,
                            }}
                        >
                            <span role="img" aria-label="清除">
                                🗑️
                            </span>{" "}
                            清除弹幕
                        </button>
                    </div>
                    {showDanmuPanel && (
                        <div
                            style={{
                                width: "100%",
                                margin: "0 auto 16px",
                                display: "flex",
                                alignItems: "center",
                                gap: 24,
                                background: "#181818",
                                borderRadius: 8,
                                padding: "12px 20px",
                                boxShadow: "0 2px 8px #0002",
                            }}
                        >
                            <label
                                style={{
                                    color: "#fff",
                                    fontWeight: 500,
                                    fontSize: 16,
                                }}
                            >
                                <input
                                    type="checkbox"
                                    checked={danmuVisible}
                                    onChange={(e) =>
                                        setDanmuVisible(e.target.checked)
                                    }
                                    style={{ marginRight: 8 }}
                                />
                                显示弹幕
                            </label>
                            <div
                                style={{
                                    display: "flex",
                                    alignItems: "center",
                                    gap: 8,
                                }}
                            >
                                <span style={{ color: "#fff", fontSize: 15 }}>
                                    字体大小
                                </span>
                                <input
                                    type="range"
                                    min={14}
                                    max={40}
                                    value={danmuFontSize}
                                    onChange={(e) =>
                                        setDanmuFontSize(Number(e.target.value))
                                    }
                                    style={{ width: 100 }}
                                />
                                <span style={{ color: "#fff", fontSize: 15 }}>
                                    {danmuFontSize}px
                                </span>
                            </div>
                        </div>
                    )}
                    <div
                        style={{
                            position: "relative",
                            width: "100%",
                            maxWidth: 800,
                        }}
                    >
                        {/* 弹幕区域 */}
                        {danmuVisible && (
                            <div
                                ref={danmuAreaRef}
                                style={{
                                    pointerEvents: "none",
                                    position: "absolute",
                                    left: 0,
                                    top: 0,
                                    right: 0,
                                    bottom: 0,
                                    width: "100%",
                                    height: "100%",
                                    zIndex: 2,
                                    overflow: "hidden",
                                }}
                            >
                                {activeDanmus.map((dm) => {
                                    const pausedLeft =
                                        pausedDanmuPositions[dm.key];
                                    const isPaused =
                                        isVideoPaused &&
                                        pausedLeft !== undefined;

                                    return (
                                        <span
                                            key={dm.key}
                                            data-danmu-key={dm.key}
                                            className={
                                                isPaused ? "danmu-paused" : ""
                                            }
                                            style={{
                                                position: "absolute",
                                                left: isPaused
                                                    ? `${pausedLeft}px`
                                                    : 0,
                                                top: dm.top,
                                                whiteSpace: "nowrap",
                                                color: "#fff",
                                                fontWeight: 700,
                                                fontSize: danmuFontSize,
                                                textShadow:
                                                    "2px 2px 4px #000, 0 0 2px #000",
                                                pointerEvents: "none",
                                                animation:
                                                    "danmu-move 8s linear",
                                                willChange: "left, opacity",
                                            }}
                                        >
                                            {dm.text}
                                        </span>
                                    );
                                })}
                            </div>
                        )}
                        <video
                            ref={videoRef}
                            src="/asd.mp4"
                            controls
                            style={{
                                width: "100%",
                                maxWidth: 800,
                                borderRadius: 16,
                                boxShadow: "0 8px 32px rgba(0,0,0,0.25)",
                                background: "#222",
                                margin: "0 auto",
                                display: "block",
                                zIndex: 1,
                            }}
                        />
                        {/* 弹幕动画样式 */}
                        <style>{`
                            @keyframes danmu-move {
                                0% { left: 100%; opacity: 1; }
                                10% { opacity: 1; }
                                85% { opacity: 1; }
                                95% { opacity: 0; }
                                100% { left: -100%; opacity: 0; }
                            }
                            
                            .danmu-paused {
                                animation-play-state: paused !important;
                            }
                        `}</style>
                    </div>
                    {/* 弹幕输入框和按钮 */}
                    <div
                        style={{
                            width: "100%",
                            maxWidth: 800,
                            margin: "32px auto 0",
                            display: "flex",
                            gap: 12,
                        }}
                    >
                        <input
                            type="text"
                            value={danmuInput}
                            onChange={(e) => setDanmuInput(e.target.value)}
                            onKeyDown={handleInputKeyDown}
                            placeholder="发送弹幕..."
                            style={{
                                flex: 1,
                                borderRadius: 8,
                                border: "none",
                                padding: "10px 16px",
                                fontSize: 16,
                                outline: "none",
                                background: "#222",
                                color: "#fff",
                                boxShadow: "0 2px 8px #0002",
                            }}
                        />
                        <button
                            onClick={handleSendDanmu}
                            style={{
                                background:
                                    "linear-gradient(90deg, #00c3ff 0%, #ffff1c 100%)",
                                color: "#222",
                                fontWeight: 700,
                                border: "none",
                                borderRadius: 8,
                                padding: "0 24px",
                                fontSize: 16,
                                cursor: "pointer",
                                boxShadow: "0 2px 8px #0002",
                                transition: "background 0.2s",
                            }}
                        >
                            发送
                        </button>
                    </div>
                </div>
            </div>
        </div>
    );
}

export default Index;
